package divestoclimb.checklist;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ListAdapter;

import divestoclimb.checklist.data.Category;
import divestoclimb.checklist.storage.DbAdapter;

/**
 * An abstract class for building a ListActivity that allows displaying items
 * based on category. A category button is used to show the current category
 * and launch an activity to change it.
 * @author Ben Roberts (divestoclimb@gmail.com)
 */
public abstract class AbsListByCategory extends ListActivity implements Button.OnClickListener {

	public static final String CATEGORY = "category";

	private DbAdapter mDbHelper;
	private Button mCategoryButton;
	private Cursor mCursor;

	private long mCategoryId;					// The category to display for this view.
												// If this is -1, we display all categories

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.list_by_category);

		mDbHelper = new DbAdapter(this);
		mDbHelper.open();
		
		Bundle params = icicle != null? icicle: getIntent().getExtras();
		if(params != null) {
			mCategoryId = params.getLong(CATEGORY, SelectCategory.ID_ALL);
		} else {
			mCategoryId = SelectCategory.ID_ALL;
		}
		
		mCategoryButton = (Button)findViewById(R.id.cat_button);
		mCategoryButton.setOnClickListener(this);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		// Because mCategoryId may have changed since onPause(), we must
		// rebuild the cursor every time.
		rebuildCursor();
		if(mCategoryId == SelectCategory.ID_ALL) { 
			mCategoryButton.setText(getString(R.string.all));
		} else {
			Category c = mDbHelper.fetchCategory(mCategoryId);
			if(c == null) {
				mCategoryId = DbAdapter.KEY_CATEGORY_ID_UNFILED;
				c = mDbHelper.fetchCategory(mCategoryId);
			}
			mCategoryButton.setText(c.getName());
		}
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putLong(CATEGORY, mCategoryId);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
		super.onActivityResult(requestCode, resultCode, intent);
		if(requestCode == SelectCategory.CODE_CATEGORY_CHANGE && resultCode == RESULT_OK) {
			mCategoryId = intent.getExtras().getLong(DbAdapter.KEY_CATEGORY_ID);
		}
	}
	
	public void onClick(View v) {
		Intent i = new Intent(this, SelectCategory.class);
		i.putExtra(SelectCategory.SHOW_ALL, true);
		startActivityForResult(i, SelectCategory.CODE_CATEGORY_CHANGE);
	}
	
	protected long getCategoryId() {
		return mCategoryId;
	}
	
	protected DbAdapter getDbHelper() {
		return mDbHelper;
	}
	
	/**
	 * Rebuilds the cursor and applies it to the ListView, swapping out an
	 * old cursor if it exists. Also handles building the CursorAdapter if it
	 * has not already been built.
	 */
	protected void rebuildCursor() {
		Cursor c = buildCursor();
		startManagingCursor(c);
		if(mCursor == null) {
			// Set up the ListAdapter
			setListAdapter(buildCursorAdapter(c));
		} else {
			// Swap out the ListView's cursor with the new one
			((CursorAdapter)getListView().getAdapter()).changeCursor(c);
			stopManagingCursor(mCursor);
			mCursor.close();
		}
		mCursor = c;
	}
	
	/**
	 * This method should return the Cursor to use for this List, built based
	 * on the parameters given to the Activity
	 * @return The cursor to use
	 */
	protected abstract Cursor buildCursor();

	/**
	 * This method should build a ListAdapter that can be applied to the ListView
	 * @param c The cursor to use for the CursorAdapter
	 * @return A ListAdapter
	 */
	protected abstract ListAdapter buildCursorAdapter(Cursor c);
}